﻿using MathNet.Numerics.LinearAlgebra.Factorization;
using MathNet.Numerics.LinearAlgebra;
using System;

namespace UtilZ.Dotnet.MathNetEx.LinearAlgebra
{

    /// <summary>
    /// 
    /// </summary>
    public abstract class QRDouble : QR<double>
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="q"></param>
        /// <param name="rFull"></param>
        /// <param name="method"></param>
        public QRDouble(Matrix<double> q, Matrix<double> rFull, QRMethod method)
            : base(q, rFull, method)
        {
        }

        /// <summary>
        /// Gets the absolute determinant value of the matrix for which the QR matrix was computed.
        /// </summary>
        public override double Determinant
        {
            get
            {
                if (FullR.RowCount != FullR.ColumnCount)
                {
                    throw new ArgumentException("Matrix must be square.");
                }

                var det = 1.0;
                for (var i = 0; i < FullR.ColumnCount; i++)
                {
                    det *= FullR.At(i, i);
                    if (MathNet.Numerics.Precision.AlmostEqual(Math.Abs(FullR.At(i, i)), 0.0))
                    {
                        return 0;
                    }
                }

                return Math.Abs(det);
            }
        }

        /// <summary>
        /// Gets a value indicating whether the matrix is full rank or not.
        /// </summary>
        /// <value><c>true</c> if the matrix is full rank; otherwise <c>false</c>.</value>
        public override bool IsFullRank
        {
            get
            {
                for (var i = 0; i < FullR.ColumnCount; i++)
                {
                    if (MathNet.Numerics.Precision.AlmostEqual(Math.Abs(FullR.At(i, i)), 0.0))
                    {
                        return false;
                    }
                }

                return true;
            }
        }
    }
}
